home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / WANDR401.ZIP / sources / Display.c next >
Encoding:
C/C++ Source or Header  |  1997-11-09  |  22.4 KB  |  922 lines

  1. /*        display.c                                   */
  2.  
  3. /* Most of the new code for wanderer has been placed here.
  4.    This file contains all the functions for the graphical
  5.    user interface of wanderer. It contains functions for
  6.    drawing on the screen, displaying status information,
  7.    the menu selector corresponding to the function
  8.    button F6 and creating audio special effects. Most
  9.    of the interaction with the ALLEGRO game development
  10.    package occurs here.
  11. */
  12.  
  13.  
  14. #include "wand_head.h"
  15. #include <allegro.h>
  16.  
  17. /* files created by allegro/tools/dat from the *.dat files */
  18. #include "wandat.h"   /* sprite definitions */
  19. #include "fonts.h"    /* font   definition  */
  20. #include "samples.h"  /* audio sample definitions */
  21.  
  22. int set_refresh =1;  /* signals whether to blit to screen or not */
  23. int tile;
  24. int active_spritebase; /* indicates the desired sprite database */ 
  25. int signal_reload;   /* signal to game.c to load a new screen */
  26.  
  27. extern char lscreen[NOOFROWS][ROWLEN+1];  /* the level map */
  28. extern char screen_name[61];
  29. extern char *edit_memory, *memory_end;  /* for storing all key strokes */
  30. extern int pause2;                     /* controls delays in playback */
  31. extern int pause1;                     /* controls speed of falling blocks */
  32. extern int debug_disp;            /* map or zoom mode */
  33. extern int leveldir;              /* chooses between directories for levels */
  34. extern int gamelevel;             /* desired starting level  */
  35. extern int spritebase;            /* desired sprite database */
  36. extern int playback_flag;         /* signals whether F5 button active */
  37. extern int audio_flag;            /* signals whether audio is on or off */
  38. extern int midi_flag;             /* signals whether midi is on or off */
  39. extern char * screenpath;         /* path name to the level directory */
  40. extern int midi_playing;          /* signals whether midi playing now */
  41. extern int vga;              /* signals svga or vga mode (1 or 2) */
  42.  
  43.  
  44. DATAFILE *data;           /* sprites */
  45. DATAFILE *datafonts;      /* font    */
  46. DATAFILE *datasamples;    /* audio samples */
  47.  
  48. BITMAP *screen;
  49. BITMAP *board;
  50. BITMAP *control_bar;
  51. MIDI   *music;
  52.  
  53. extern int nx,ny;   /* coordinates of explorer */
  54. extern int levelnum;
  55. int tilespace = 16;
  56. int fontsel = font18;
  57.  
  58. show_cover()
  59. {
  60. BITMAP *cover;
  61. RGB pall[256];
  62. clear_to_color(screen,0);
  63. cover = load_pcx("cover.pcx",pall);
  64. set_pallete(pall);
  65. blit(cover,screen,0,0,0,0,320,240);
  66. destroy_bitmap(cover);
  67. getch();
  68. clear_to_color(screen,0);
  69. }
  70.  
  71. create_bitmaps()
  72. /* creates the bitmaps for storing the game level. */
  73. /* We need board bitmap so we can zoom and scroll. */ 
  74. /* The screen bitmap comes for free with ALLEGRO. */
  75. {
  76. board = create_bitmap(640,256);
  77. if(board == NULL)
  78.     {alert_crash("Not enough memory to create bitmap"); exit(0);}
  79. control_bar = create_bitmap(640,40);
  80. clear(board);
  81. clear(control_bar);
  82. }
  83.  
  84.  
  85. load_datafiles()
  86. {
  87. /*  Load the Allgero datafile. These were created by */
  88. /*  grabber and xspred.                              */
  89.  if(vga == 2) 
  90.    {
  91.    fontsel = font9;
  92.    tilespace = 8;
  93.    }
  94.  change_spritebase();
  95.  datafonts = load_datafile("dat/fonts.dat");
  96.  if(datafonts == NULL)
  97.    {alert_crash("unable to load file fonts.dat"); exit(0);}
  98.  datasamples = load_datafile("dat/samples.dat");
  99.  if(data == NULL)
  100.    {alert_crash("unable to load file wandspr0.dat"); exit(0);}
  101.  if(datasamples == NULL) 
  102.    {alert_crash("unable to load file samples.dat"); exit(0);}
  103.  set_pallete(data[PAL].dat);
  104.  active_spritebase=0;
  105. }
  106.  
  107.  
  108. change_spritebase()
  109. {
  110. /* This code permits flipping between the sprite databases */
  111. unload_datafile(data);
  112.  switch (spritebase)
  113.   {
  114.   case 0:
  115.   if(vga == 2)
  116.   data = load_datafile("dat/vgaspr0.dat");
  117.   else
  118.   data = load_datafile("dat/wandspr0.dat");
  119.   break;
  120.  
  121.   case 1:
  122.   if(vga == 2)
  123.   data = load_datafile("dat/vgaspr1.dat");
  124.   else
  125.   data = load_datafile("dat/wandspr1.dat");
  126.   break;
  127.  
  128.   default:
  129.   if(vga == 2)
  130.   data = load_datafile("dat/vgaspr1.dat");
  131.   else
  132.   data = load_datafile("dat/wandspr1.dat");
  133.   }
  134. if(data == NULL) alert_crash("Trouble loading wandspr* data.");
  135. active_spritebase = spritebase;
  136. }  
  137.  
  138.  
  139. change_leveldir()
  140. {
  141. /* This code permits flipping between the level subdirectories */
  142. switch (leveldir)
  143.  {
  144.   case 0:
  145.   screenpath = "./easy";
  146.   break;
  147.  
  148.   case 1:
  149.   screenpath = "./screens";
  150.   break;
  151.  
  152.   default:
  153.   screenpath = "./screens";
  154.   break;
  155.   }
  156. }
  157.  
  158.  
  159. char * bar_str[7] = {"quit", "help", "about", "size", "restart",
  160.  "playback","configure"};
  161.  
  162. make_control_bar()
  163. {
  164. /* Creates the bitmap of the control bar which appears on top of the      */
  165. /* screen. The control bar is not mouse sensitive but is just informative */
  166. /* to  the player.                                                        */
  167. int i;
  168. int width;
  169. char str[32];
  170. clear_to_color(control_bar,28);
  171. text_mode(-1);
  172. width=75+(vga-1)*15;
  173. for (i=0;i<7;i++)
  174.   {
  175.   rectfill(control_bar,i*width/vga+1,1,(i+1)*width/vga-1
  176.       ,38/vga-(vga-1)*2,24);
  177.   line(control_bar,i*width/vga+2,2,(i+1)*width/vga-1,2,20);
  178.   line(control_bar,i*width/vga+2,2,i*width/vga+2,38/vga-(vga-1)*2,20);
  179.   if(i==0) sprintf(str,"ESC");
  180.   else sprintf(str,"F%d",i);
  181.   textout(control_bar,datafonts[fontsel].dat,str,i*width/vga+4,4,4);
  182.   if (playback_flag || i != 5)
  183.     textout(control_bar,datafonts[fontsel].dat,bar_str[i],i*width/vga+4
  184.      ,21/vga,4);
  185.   }
  186. blit(control_bar,screen,0,0,80-40*vga,0,width*7/vga,40);
  187. text_mode(0);
  188. }
  189.  
  190. /* The next three functions display the board bitmap onto */
  191. /* the screen in VGA (640 x 480) graphics; either in map  */
  192. /* mode or zoom/scrolling mode.                           */
  193.  
  194. void refresh_board()
  195. {
  196. blit(board,screen,0,0,0,42/vga,640/vga,256/vga);
  197. }
  198.  
  199.  
  200. void refresh_scroll_board()
  201. {
  202. int scroll_x,scroll_y;
  203. scroll_x = nx-10;
  204. scroll_y = ny-10;
  205. if(scroll_x <0) scroll_x =0;
  206. if(scroll_y <0) scroll_y =0;
  207. if(scroll_x>20) scroll_x= 20;
  208. if(scroll_y>4)  scroll_y=4;
  209. if(vga == 1)
  210.   stretch_blit(board,screen,scroll_x*tilespace,scroll_y*tilespace,
  211.     320,192,0,42,640,386);
  212. else
  213.   stretch_blit(board,screen,scroll_x*tilespace,scroll_y*tilespace,
  214.     160,96,0,21,320,193);
  215. }
  216.  
  217. void refresh_screen()
  218. {
  219. if(debug_disp) refresh_board();
  220. else refresh_scroll_board();
  221. }
  222.  
  223.  
  224. void clear_remnant()
  225. /* There is a little piece on the screen we have to clear when we */
  226. /* switch from zoom mode back to map mode. This function is called*/
  227. /* in game.c                                                      */
  228. {
  229. rectfill(screen,0,257/vga,639/vga,427/vga,0);
  230. }
  231.  
  232.  
  233. /* To provide variety there are different background tiles that
  234.    we can use to represent free space. The tile is chosen based
  235.    on the level number of the screen.
  236. */
  237.  
  238. int select_tile(level)
  239. int level;
  240. {
  241. int i,itile;
  242. i= level%5;
  243.  
  244. switch (i)
  245.  {
  246.  case 0:
  247.   itile = ZTILE1;
  248.   break;
  249.  
  250.  case 1:
  251.   itile = ZTILE2;
  252.   break;
  253.  
  254.  case 2:
  255.   itile = ZTILE3;
  256.   break;
  257.  
  258.  case 3:
  259.   itile = ZTILE4;
  260.   break;
  261.  
  262.  case 4:
  263.   itile = ZTILE5;
  264.   break;
  265.   }
  266. return itile;
  267. }
  268.  
  269.  
  270. void draw_object (y, x, glyph)
  271.      int x, y;
  272.      char glyph;
  273. /* This function is used to modify the tile on the board bitmap. */
  274. /* It is called in many places in game.c, fall.c and monsters.c. */ 
  275. /* First we draw the background tile (representing free space).  */
  276. /* In order to get a nice lattice we flip alternate tiles left to*/
  277. /* right or up to down. Then we paste in transparent mode the    */
  278. /* other sprites.                                                */
  279. {
  280.   int spr;
  281.   int i,j,k;
  282.   char str[4];
  283.   i = x%2;
  284.   j = y%2;
  285.   k = i + (j<<1);
  286.   switch (k)  /* for proper tesselation of tiles */
  287.    {
  288.    case 0:
  289.    draw_sprite (board, data[tile].dat, x * tilespace, y * tilespace);
  290.    break;
  291.  
  292.    case 1:
  293.    draw_sprite_h_flip(board, data[tile].dat, x * tilespace, y * tilespace);
  294.    break;
  295.  
  296.    case 2:
  297.    draw_sprite_v_flip (board, data[tile].dat, x * tilespace, y * tilespace);
  298.    break;
  299.  
  300.    case 3:
  301.    draw_sprite_vh_flip (board, data[tile].dat, x * tilespace, y * tilespace);
  302.    break;
  303.    }
  304.  
  305. /* ARRIVE, ARROWR etc were defined in wandat.h             */
  306.   switch (glyph)
  307.     {
  308.     case 'A':
  309.       spr = ARRIVE;
  310.       break;
  311.     case '>':
  312.       spr = ARROWR;
  313.       break;
  314.     case '<':
  315.       spr = ARROWL;
  316.       break;
  317.     case 'S':
  318.       spr = BABY_MONSTER;
  319.       break;
  320.     case '\\':
  321.       spr = BACKSLASH;
  322.       break;
  323.     case '^':
  324.       spr = BALLOON;
  325.       break;
  326.     case 'O':
  327.       spr = BOULDER;
  328.       break;
  329.     case '+':
  330.       spr = CAGE;
  331.       break;
  332.     case '*':
  333.       spr = DIAMOND;
  334.       break;
  335.     case ':':
  336.       spr = DUST;
  337.       break;
  338.     case 'X':
  339.       spr = EXIT;
  340.       break;
  341.     case '@':
  342.       spr = EXPLORER;
  343.       break;
  344.     case '!':
  345.       spr = MINE;
  346.       break;
  347.     case 'M':
  348.       spr = MONSTER;
  349.       break;
  350.     case '#':
  351.       spr = ROCK1;
  352.       break;
  353.     case '=':
  354.       spr = ROCK2;
  355.       break;
  356.     case '/':
  357.       spr = SLASH;
  358.       break;
  359.     case 'T':
  360.       spr = TELEPORT;
  361.       break;
  362.     case ' ':
  363.       spr = BLANK;
  364.       break;
  365.     case 'C':
  366.       spr = TIMECAPSULE;
  367.       break;
  368.     case 'B':
  369.       spr = BOMB;
  370.       break;
  371.     case '~':
  372.       spr = THINGY;
  373.       break;
  374.     default:
  375.       text_mode(-1);
  376.       spr = BLANK;
  377.       sprintf(str,"%c",glyph);
  378.       textout(board,datafonts[fontsel].dat,str,
  379.         x*tilespace,y*tilespace,1);
  380.       text_mode(1);
  381.     }
  382.   draw_sprite (board, data[spr].dat, x * tilespace, y * tilespace);
  383.   if(set_refresh) refresh_screen();
  384. }
  385.  
  386.  
  387. void map (row_ptr)
  388. char (*row_ptr)[ROWLEN + 1];
  389. {
  390. /* This function creates the whole board bitmap after we have */
  391. /* loaded a new level or restarted the same level.            */
  392.   int x, y;
  393.   char ch;
  394.  
  395.   set_refresh=0;   /* we don't want to do a whole screen blit each */
  396.                    /* time we call draw_object.                    */ 
  397.   tile = select_tile(levelnum);
  398.   for (y = 0; y < NOOFROWS; y++)
  399.     {
  400.     for (x = 0; x < ROWLEN; x++)
  401.       {
  402.     ch = row_ptr[y][x];
  403.     draw_object (y, x, ch);
  404.       }
  405.     }
  406.   refresh_screen();
  407. }
  408.  
  409.  
  410.  
  411.  
  412. void redraw_screen( maxmoves, num, score, nf, diamonds, mx, sx, sy, frow)
  413.  
  414. int  maxmoves, num, nf, diamonds, mx, sx, sy;
  415. long score;
  416. char (*frow)[ROWLEN+1];
  417. {
  418. char buffer[50];
  419.  
  420. clear_to_color(screen,0);
  421.  
  422. make_control_bar();
  423.  
  424. notify_screen_name(num,screen_name);
  425.  
  426. map(frow);
  427. }
  428.  
  429. /*           NOTIFICATION AND ALERT FUNCTIONS       */
  430.  
  431.  
  432. notify_screen_name(num,name)
  433. int num;
  434. char * name;
  435. {
  436. char str[80];
  437. if ((name[0] == '#') || (name[0] == '\0'))
  438.    sprintf(name,"no name            ");
  439. sprintf(str,"screen %2d :%s",num,name);
  440. rectfill(screen,0,440/vga,450/vga,458/vga,0);
  441. textout(screen,datafonts[fontsel].dat,str,0,440/vga,4);
  442. }
  443.  
  444.  
  445. notify_score(score)
  446. int score;
  447. {
  448. char str[30];
  449. sprintf(str,"score=%4d  ",score);
  450. textout(screen,datafonts[fontsel].dat,str,0,460/vga,4);
  451. }
  452.  
  453.  
  454. notify_diamonds(nf,diamonds)
  455. int nf,diamonds;
  456. {
  457. char str[30];
  458. sprintf(str,"diamonds=%3d/%-2d  ",nf,diamonds);
  459. textout(screen,datafonts[fontsel].dat,str,130/vga,460/vga,4);
  460. }
  461.  
  462.  
  463. notify_maxmoves(moves)
  464. int moves;
  465. {
  466. char str[30];
  467. if(moves != -1)
  468. sprintf(str,"%4d moves left   ",moves);
  469. else
  470. sprintf(str,"maxmoves=no limit");
  471. textout(screen,datafonts[fontsel].dat,str,320/vga,460/vga,4);
  472. }
  473.  
  474.  
  475.  
  476. /*              POPUP  WINDOWS                              */
  477. /* The next three functions are used to send a message      */
  478. /* via a popup window. The first function is fairly general */
  479. /* and can be used sending warning messages, like file not  */
  480. /* found. The other two functions have specific purposes.   */
  481.  
  482. alert_message(msg)
  483. char *msg;
  484. {
  485. while (kbhit()) getch(); /* clear keyboard buffer */
  486. rectfill(screen,100/vga,300/vga,400/vga+(vga-1)*30,360/vga,24);
  487. text_mode(-1);
  488. textout(screen,datafonts[fontsel].dat,msg,120/vga,320/vga,4);
  489. textout(screen,datafonts[fontsel].dat,"Hit any key to continue"
  490.     ,120/vga,340/vga,4);
  491. getch();
  492. rectfill(screen,100/vga,300/vga,400/vga+(vga-1)*30,360/vga,0);
  493. text_mode(1);
  494. }
  495.  
  496. alert_crash(msg)
  497. char *msg;
  498. {
  499. while (kbhit()) getch(); /* clear keyboard buffer */
  500. rectfill(screen,100/vga,300/vga,400/vga,360/vga,24);
  501. text_mode(-1);
  502. textout(screen,font,msg,120/vga,320/vga,4);
  503. textout(screen,font,"Hit any key to continue",120/vga,340/vga,4);
  504. getch();
  505. rectfill(screen,100/vga,300/vga,400/vga,360/vga,0);
  506. text_mode(1);
  507. }
  508.  
  509.  
  510. int alert_kill_status(msg)
  511. char *msg;
  512. {
  513. char ch;
  514. char str[60];
  515. sprintf(str,"Killed by %s",msg);
  516. rectfill(screen,300/vga,380/vga,570/vga+(vga-1)*40,460/vga,24);
  517. text_mode(-1);
  518. textout(screen,datafonts[fontsel].dat,str,310/vga,390/vga,4);
  519. textout(screen,datafonts[fontsel].dat,"Press any key to continue."
  520.   ,310/vga,420/vga,4);
  521. textout(screen,datafonts[fontsel].dat,"ESC key exits the game."
  522.   ,310/vga,435/vga,4);
  523. rest(500);
  524. text_mode(1);
  525. while (kbhit()) getch(); /* clear keyboard buffer */
  526. ch = getkey();
  527. rectfill(screen,300/vga,380/vga,570/vga+(vga-1)*40,460/vga,0);
  528. if (ch == 27) return 1;
  529. else return 0;
  530. }
  531.  
  532. char *congrat_msg1[] = {"Congratulations, you completed this level",
  533.             "for the first time. The solution has been",
  534.             "saved in the subdrectory solu. Please ",
  535.             "e-mail the solutions to me."};
  536.  
  537. char *congrat_msg2[] = {"Congratulations, you found a better",
  538.             "solution. It shall replace the old",
  539.             "solution in the subdirectory solu." };
  540.  
  541.  
  542. alert_congratulations(select)
  543. int select;
  544. {
  545. int i;
  546. rectfill(screen,200/vga,340/vga,575/vga+(vga-1)*30,425/vga,24);
  547. text_mode(-1);
  548. if(select == 0)
  549.   for (i=0;i<4;i++)
  550.    textout(screen,datafonts[fontsel].dat,congrat_msg1[i]
  551.       ,205/vga,(350 + i*15)/vga,4);
  552. else
  553.   for (i=0;i<3;i++)
  554.    textout(screen,datafonts[fontsel].dat,congrat_msg2[i]
  555.      ,205/vga,(350 + i*15)/vga,4);
  556.  
  557. text_mode(0);
  558. rest(2000);
  559. getch();
  560. rectfill(screen,200/vga,340/vga,575/vga+(vga-1)*30,425/vga,0);
  561. }
  562.  
  563.  
  564.  
  565. /*     Unless you use the cntl-W, cntl-R keys for saving
  566.        and restoring your solution files, you will not
  567.        use this code. This code is here to maintain the
  568.        old functions in the original wanderer code. It
  569.        is also useful for testing and debugging.
  570. */ 
  571.        
  572.  
  573.  
  574. notify_message(msg)
  575. char *msg;
  576. {
  577.   textout(screen,datafonts[fontsel].dat,msg,240/vga,380/vga,4);
  578. }
  579.  
  580.  
  581. clear_notify_message()
  582. {
  583. notify_message("                                   ");
  584. }
  585.  
  586.  
  587. /* entering textual information in ALLEGRO is a little
  588.    tricky, because you can no longer depend on printf,
  589.    scanf functions after switching to VGA mode. The
  590.    falling function tries to mimic scanf for inputting
  591.    a character string. (i.e support the rubout key.)
  592.    It doesn't do a perfect job, but it is adequate.
  593. */
  594. char readtext(str, size, ix, iy, col)
  595. char *str;
  596. int size;
  597. int ix,iy,col;
  598. {
  599. /* read and echos char string input up to size letters */
  600. /* ix,iy,col place and colour to echo string           */
  601.     char *string;
  602.     int count = 0;
  603.     char ch;
  604.  
  605.     string = str;
  606.     for (;;) {
  607.     ch = getch();
  608.     if (ch == 13) {
  609.         *str = '\0';
  610.         break;
  611.     }
  612.  
  613.         if(ch==0) ch=getch();
  614.  
  615.     if ((ch == '\010') || (ch == 83)) {
  616.         if (count == 0)
  617.         continue;
  618.         str--; count--;
  619.             *str = ' ';
  620.         textout(screen,datafonts[fontsel].dat,string,ix,iy,col);
  621.         continue;
  622.     }
  623.     if (count == size) {
  624.         printf("\007");
  625.             fflush(stdout);
  626.         continue;
  627.     }
  628.     *str = ch;
  629.     str++; count++;
  630.         *str = '\0';
  631.         textout(screen,datafonts[fontsel].dat,string,ix,iy,col);
  632.     }
  633. }
  634.  
  635. /* The following 4 functions allow the user to specify the
  636.    filename for saving, restoring game files and solution files.
  637.    That is it provides supports for the R, S Cntl-R and Cntl-W
  638.    commands available in wand330.zip. Now these commands are
  639.    only used for diagnostics and debugging.
  640. */
  641.  
  642. save_game_file_name(name)
  643. char *name;
  644. {
  645. notify_message("Save game file name:");
  646. readtext(name,40,420 - (vga-1)*180, 380/vga,4);
  647. rectfill(screen,240/vga,370/vga,580/vga,430/vga,0);
  648. }
  649.  
  650. restore_game_file_name(name)
  651. char *name;
  652. {
  653. notify_message("Restore game file name:");
  654. readtext(name,40,430 - (vga-1)*190,380/vga,4);
  655. rectfill(screen,240/vga,370/vga,580/vga,430/vga,0);
  656. }
  657.  
  658.  
  659. save_soln_file_name(name)
  660. char *name;
  661. {
  662. notify_message("Save solution file name:");
  663. readtext(name,40,420 - (vga-1)*180,380/vga,4);
  664. rectfill(screen,240/vga,370/vga,580/vga,430/vga,0);
  665. }
  666.  
  667. load_soln_file_name(name)
  668. char *name;
  669. {
  670. notify_message("solution file name to load:");
  671. readtext(name,40,440 - (vga-1)*185,380/vga,4);
  672. rectfill(screen,240/vga,370/vga,580/vga,430/vga,0);
  673. }
  674.  
  675.  
  676. /*            AUDIO                            */
  677.  
  678.  
  679. play_audio_sample(int n)
  680. {
  681. play_sample(datasamples[n].dat,150,55,1000,0);
  682. }
  683.  
  684.  
  685. /*            MIDI                            */
  686.  
  687. /* read the list of midi files in the file ./mids/index */
  688.  
  689. char midifiles[20][32];
  690.  
  691. int n_midi;
  692.  
  693. read_midis()
  694. {
  695. FILE *handle;
  696. char buffer[32];
  697. char *ret;
  698. if(exists("./mids/index"))
  699.   {
  700.   n_midi=0;
  701.   handle = fopen("./mids/index","rt");
  702.   while(fgets(buffer,32,handle) && n_midi<20)
  703.    {
  704.    sscanf(buffer,"%s",midifiles[n_midi]);
  705. //   printf("%s\n",midifiles[n_midi]);
  706.    n_midi++;
  707.    }
  708.   }
  709. }
  710.  
  711. load_and_play_midi()
  712. {
  713. char buffer[32],message[64];
  714. if(midi_playing) destroy_midi(music);
  715. sprintf(buffer,"./mids/%s",midifiles[(gamelevel-1) % n_midi]);
  716. if(exists(buffer))
  717.   {
  718.   music = load_midi(buffer);
  719.   play_midi(music,0);
  720.   midi_playing=1;
  721.   }
  722. else
  723.  {
  724.   sprintf(message,"can't find %s",buffer);
  725.   alert_message(message);
  726.   midi_playing=0;
  727.  }
  728. }
  729.  
  730. switch_off_midi()
  731. {
  732. if(midi_playing) destroy_midi(music);
  733. midi_playing =0;
  734. }
  735.  
  736.  
  737.  
  738.  
  739. /*      MENU SUPPORT FUNCTIONS              */
  740.  
  741. #define UP_ARROW 328
  742. #define DOWN_ARROW 336
  743. #define LEFT_ARROW 331
  744. #define RIGHT_ARROW 333
  745. #define ESC 27
  746. #define CR 13
  747.  
  748. #define MENU_TOP 100
  749. #define MENU_LEFT 100
  750.  
  751. char *menuheaders[7] =
  752. {"level set", "sprites", "starting level",
  753.  "animation", "playback" ,"audio", "music"};
  754. char *menuhelp[7] =
  755. {
  756.  "Select directory for finding levels",
  757.  "Select the set of sprites to use",
  758.  "Begin game at this level",
  759.  "Large numbers slow down animation",
  760.  "Large numbers slow down playback",
  761.  "Turn audio effects on or off",
  762.  "Turn background music on or off "};
  763.  
  764.  
  765. int menupar[7];
  766.  
  767.  
  768. show_menu (int item)
  769. {
  770.   char string[20];
  771.   int i;
  772.  
  773.   rectfill (screen, (MENU_LEFT+10)/vga, (MENU_TOP+ 20)/vga,
  774.             (MENU_LEFT+ 320)/vga+(vga-1)*40, (MENU_TOP+ 180)/vga, 24);
  775.   for (i = 0; i < 7; i++)
  776.     {
  777.       if (i == item)
  778.     textout (screen, datafonts[fontsel].dat, menuheaders[i]
  779.            ,(MENU_LEFT+20)/vga,(MENU_TOP+ 30 + 15 * i)/vga, 4);
  780.       else
  781.     textout (screen, datafonts[fontsel].dat, menuheaders[i],
  782.            (MENU_LEFT+20)/vga, (MENU_TOP + 30 + 15 * i)/vga, 5);
  783.     }
  784.   if (menupar[0] == 0)
  785.     textout(screen,datafonts[fontsel].dat,"training levels"
  786.        ,(MENU_LEFT+160)/vga,(MENU_TOP+30)/vga,1);
  787.   else 
  788.     textout(screen,datafonts[fontsel].dat,"standard levels"
  789.       ,(MENU_LEFT+160)/vga,(MENU_TOP+30)/vga,1);
  790.  
  791.   if (menupar[1] == 1)
  792.     textout(screen,datafonts[fontsel].dat,"girl explorer"
  793.       ,(MENU_LEFT+160)/vga, (MENU_TOP+30 + 15)/vga, 1);
  794.   else
  795.     textout(screen,datafonts[fontsel].dat,"baby explorer"
  796.       ,(MENU_LEFT+160)/vga, (MENU_TOP+30 + 15)/vga, 1);
  797.  
  798.   sprintf(string,"%2d",menupar[2]);
  799.   textout (screen, datafonts[fontsel].dat, string,
  800.         (MENU_LEFT+160)/vga, (MENU_TOP+30 + 30)/vga , 1);
  801.  
  802.   sprintf(string,"%2d",menupar[3]);
  803.   textout (screen, datafonts[fontsel].dat, string
  804.       , (MENU_LEFT+160)/vga, (MENU_TOP+30 + 45)/vga , 1);
  805.  
  806.   sprintf(string,"%2d",menupar[4]);
  807.   textout (screen, datafonts[fontsel].dat, string, 
  808.      (MENU_LEFT+160)/vga, (MENU_TOP+30 + 60)/vga , 1);
  809.  
  810.   if(menupar[5]) 
  811.     textout (screen, datafonts[fontsel].dat, "on", 
  812.        (MENU_LEFT+160)/vga, (MENU_TOP+30 + 75)/vga , 1);
  813.    else
  814.     textout (screen, datafonts[fontsel].dat, "off", 
  815.        (MENU_LEFT+160)/vga, (MENU_TOP+30 + 75)/vga , 1);
  816.  
  817.   if(menupar[6]) 
  818.     textout (screen, datafonts[fontsel].dat, "on", 
  819.        (MENU_LEFT+160)/vga, (MENU_TOP+30 + 90)/vga , 1);
  820.    else
  821.     textout (screen, datafonts[fontsel].dat, "off", 
  822.        (MENU_LEFT+160)/vga, (MENU_TOP+30 + 90)/vga , 1);
  823.  
  824.   textout (screen, datafonts[fontsel].dat,
  825.         menuhelp[item], (MENU_LEFT+20)/vga, (MENU_TOP+140)/vga, 6);
  826.   textout (screen, datafonts[fontsel].dat, "Use arrow keys or ESC"
  827.         ,(MENU_LEFT+20)/vga,(MENU_TOP+155)/vga,6);
  828.  
  829. }
  830.  
  831.  
  832. menu_interface ()
  833. {
  834.   int item;
  835.   int key_in;
  836.   menupar[0] = leveldir;
  837.   menupar[1] = spritebase;
  838.   menupar[2] = gamelevel;
  839.   menupar[3] = pause1;
  840.   menupar[4] = pause2;
  841.   menupar[5] = audio_flag;
  842.   menupar[6] = midi_flag;
  843.   item = 0;
  844.   signal_reload = 0;
  845.   text_mode (-1);
  846.   show_menu (item);
  847.   do
  848.     {
  849.       key_in = getkey();
  850.       if (key_in == UP_ARROW && item > 0)
  851.     item--;
  852.       else if (key_in == DOWN_ARROW && item < 6)
  853.     item++;
  854.       else if (key_in == LEFT_ARROW)
  855.         {
  856.         if (item == 0)
  857.            menupar[0] = 1- menupar[0];
  858.         else if (item == 1)
  859.            menupar[1] = 1 - menupar[1];
  860.         else if (item == 2 && menupar[2] >1)
  861.            menupar[2] -= 1;
  862.         else if (item == 3 && menupar[3] >5)
  863.            menupar[3] -= 5; 
  864.         else if (item == 4 && menupar[4] >5)
  865.            menupar[4] -= 5; 
  866.         else if (item == 5) 
  867.            menupar[5] = 1 - menupar[5]; 
  868.         else if (item == 6) 
  869.            menupar[6] = 1 - menupar[6]; 
  870.         }
  871.       else if (key_in == RIGHT_ARROW)
  872.         {
  873.         if (item == 0 )
  874.            menupar[0] = 1 - menupar[0];
  875.         else if (item == 1)
  876.            menupar[1] = 1 - menupar[1];
  877.         else if (item == 2 && menupar[2] < 60)
  878.            menupar[2] += 1;
  879.         else if (item == 3)
  880.            menupar[3] += 5; 
  881.         else if (item == 4)
  882.            menupar[4] += 5; 
  883.         else if (item == 5) 
  884.            menupar[5] = 1 - menupar[5]; 
  885.         else if (item == 6) 
  886.            menupar[6] = 1 - menupar[6]; 
  887.         }
  888.       show_menu (item);
  889.     }
  890.    while (key_in != ESC && key_in != CR);
  891.   text_mode(1);
  892.   if(leveldir != menupar[0])
  893.      {
  894.      leveldir = menupar[0];
  895.      change_leveldir();
  896.      signal_reload = 1;
  897.      }
  898.   if (midi_flag != menupar[6])
  899.     {
  900.     if(menupar[6]) load_and_play_midi();
  901.     else switch_off_midi();
  902.     }
  903.  
  904.   if(menupar[2] != gamelevel) signal_reload = 1;
  905.  
  906.   leveldir = menupar[0];
  907.   spritebase = menupar[1];
  908.   gamelevel = menupar[2];
  909.   pause1 = menupar[3];
  910.   pause2 = menupar[4];
  911.   audio_flag = menupar[5];
  912.   midi_flag  = menupar[6];
  913.  
  914.   if (active_spritebase != spritebase)
  915.     {
  916.     change_spritebase();
  917.     map(lscreen);
  918.     }
  919. }
  920.  
  921.  
  922.